package main

import (
	"encoding/json"
	"fmt"
	MQTT "github.com/eclipse/paho.mqtt.golang"
	socketio "github.com/googollee/go-socket.io"
	"github.com/kataras/iris"
	"github.com/kataras/iris/middleware/logger"
	"github.com/kataras/iris/middleware/recover"

	"iris/mqtt"
	"log"
)




var info struct{
	UserId string `json:"userId"`
	ChannelId int `json:"channelId"`
	IsSubscribe int `json:"isSubscribe"`
}

var message struct{
	Message string `json:"text"`
	ChannelId int `json:"channelId"`
	UserId string `json:"userId"`
}

var ClientId string
var Clients = make(map[string]MQTT.Client)

var id string

type Payload struct{
	Client string `json:"client"`
	Content string `json:"content"`
}


func main() {










	app := iris.New()
	app.Use(recover.New())
	app.Use(logger.New())
	app.Logger().SetLevel("debug")


	server, err := socketio.NewServer(nil)

	if err != nil {
		log.Fatal(err)
	}
	server.OnConnect("/roomName", func(s socketio.Conn) error {
		s.SetContext("")
		ClientId = s.ID()
		fmt.Println("connected:", s.ID())

		Client := mqtt.NewOption("tcp://127.0.0.1:11883",ClientId)
		Clients[ClientId] = Client
		mqtt.SelfSubscribe(Client,"go-mqtt/1",0,mqtt.MessageHandler1)
		mqtt.SelfSubscribe(Client,"go-mqtt/2",0,mqtt.MessageHandler2)

		s.Join("roomName")

		err := server.JoinRoom("/roomName","roomName",s)
		if err != true {
			log.Fatal(err)
		}
		return nil
	})





	server.OnEvent("/chat", "msg", func(s socketio.Conn, msg string) string {
		s.SetContext(msg)
		s.Emit("reply", ClientId)
		return ClientId
	})
	server.OnEvent("/", "bye", func(s socketio.Conn) string {
		last := s.Context().(string)
		s.Emit("bye", last)
		s.Close()
		return last
	})
	server.OnError("/", func(s socketio.Conn, e error) {
		fmt.Println("meet error:", e)
	})
	server.OnDisconnect("/", func(s socketio.Conn, reason string) {
		fmt.Println("closed", reason)
	})
	go server.Serve()
	defer server.Close()







	//app.RegisterView(iris.HTML("./src/iris/public/views", ".html"))

	//app.Get("/", func(ctx iris.Context) {
	//
	//
	//	ctx.View("index.html")
	//})

	topics := map[int]string{
		1 : "go-mqtt/1",
		2 : "go-mqtt/2",

	}

	app.Post("/changeSubscribe", func(ctx iris.Context) {

		error := ctx.ReadJSON(&info)
		if(error != nil){
			panic(error)
		}
		if(info.ChannelId == 1){
			changeSubscribe(Clients[info.UserId],topics[info.ChannelId],info.IsSubscribe,mqtt.MessageHandler1)
		}else{
			changeSubscribe(Clients[info.UserId],topics[info.ChannelId],info.IsSubscribe,mqtt.MessageHandler2)
		}

		ctx.JSON(map[string]interface{}{

			"status": 200,
		})
	})


	app.Post("/sendMessage", func(ctx iris.Context) {

		error := ctx.ReadJSON(&message)
		if(error != nil){
			panic(error)
		}
		fmt.Println(message.ChannelId)
		msg := Payload{message.UserId,message.Message}
		jsonString, _ := json.Marshal(msg)
		info := string(jsonString)
		sendMessage(info,Clients[message.UserId],topics[message.ChannelId])
		ctx.JSON(map[string]interface{}{

			"status": 200,
		})
	})


	app.HandleMany("GET POST", "/socket.io", iris.FromStd(server))
	app.HandleDir("/", "./src/iris/public/views")


	go func() {
		for {
			message, ok := <- mqtt.MsgCh

			if(ok){


				newinfo := new(Payload)
				json.Unmarshal([]byte(message.Content), newinfo)
				reply:= fmt.Sprintf("用户%s收到来自频道%d,用户%s发的消息:%s",message.ClientId,message.ChannelId,newinfo.Client,newinfo.Content)
				err := server.BroadcastToRoom("/roomName","roomName","reply",reply)
				if(err != true){
					log.Fatal(err)
				}
			}
		}
	}()



	app.Run(iris.Addr(":8080"), iris.WithoutServerError(iris.ErrServerClosed))

}




func changeSubscribe(user MQTT.Client,topic string,isSubscribe int,handler MQTT.MessageHandler)  {

	if isSubscribe == 0 {
		mqtt.SelfSubscribe(user,topic,0,handler)
	}else {
		mqtt.SelfUnSubscribe(user,topic)
	}

}

func sendMessage(message string,user MQTT.Client,topic string)  {
	token := user.Publish(topic, 2, false, message)
	token.Wait()
}